home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2007 December
/
PCWKCD1207B.iso
/
Blogowanie poza sfera
/
Flock 1.0 beta
/
flock-1.0RC3.en-US.win32.exe
/
flock
/
modules
/
onlineFavoritesBackend.jsm
< prev
next >
Wrap
Text File
|
2007-10-18
|
15KB
|
451 lines
// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2007
// http://flock.com
//
// This file may be used under the terms of of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// END FLOCK GPL
var EXPORTED_SYMBOLS = ["onlineFavoritesBackend"];
const CC = Components.classes;
const CI = Components.interfaces;
const CR = Components.results;
const CU = Components.utils;
CU.import("resource:///modules/FlockScheduler.jsm");
/**************************************************************************
* Module: Online Favorites Back End
**************************************************************************/
/* Note: This module depends on access to the following PRIVATE properties
of the services being supported:
- aService._coop
- aService._logger
- aService._c_svc
*/
// Bookmark stream refresh interval in seconds.
const DEFAULT_REFRESH_INTERVAL = 5 * 60;
const PREF_ONLINEFAVE_REFRESH_INTERVAL = "flock.favorites.online.refreshInterval";
CC["@mozilla.org/moz/jssubscript-loader;1"]
.getService(CI.mozIJSSubScriptLoader)
.loadSubScript("chrome://flock/content/common/flocksafe.js");
/**************************************************************************
* Private Data and Functions
**************************************************************************/
// Helper function to assist in comparing strings.
function stringify(aObj) {
if (!aObj) {
return "";
} else {
return aObj;
}
}
// Helper function to assist in comparing dates.
function dateify(aObj) {
if (!aObj) {
return 0;
} else {
return aObj.getTime();
}
}
// Helper function to assist in comparing lists of tags.
function sanitizeTags(aTagList) {
return aTagList ? aTagList.split(/[\s,]/).sort().join(",") : "";
}
// Helper function to assist in comparing complete bookmarks.
function bookmarks_match(bm1, bm2) {
return (bm1.private === bm2.private && /* booleans - nice and easy */
stringify(bm1.name) === stringify (bm2.name) &&
stringify(bm1.description) === stringify(bm2.description) &&
sanitizeTags(bm1.tags) === sanitizeTags(bm2.tags) &&
dateify(bm1.datevalue) === dateify(bm2.datevalue));
}
/**************************************************************************
* Online Favorites Back End Public Interface
**************************************************************************/
var onlineFavoritesBackend = {};
onlineFavoritesBackend.createAccount =
function OFBE_createAccount(aService, aAccountID, aIsTransient) {
var account_urn = aService.urn + ":" + aAccountID;
var account;
if (!aService._coop.Account.exists(account_urn)) {
account = new aService._coop.Account(account_urn, {
name: aAccountID,
serviceId: aService.contractId,
service: aService._c_svc,
accountId: aAccountID,
favicon: aService.icon,
URL: aService.getUserUrl(aAccountID),
isTransient: aIsTransient,
showInSidebar: false
});
aService._coop.accounts_root.children.addOnce(account);
} else {
account = aService._coop.get(account_urn);
}
// Create a "stream" for the online bookmarks
var bookmarks = {};
var bookmarks_urn = account_urn + ":bookmarks";
if (!aService._coop.OnlineBookmarksStream.exists(bookmarks_urn)) {
prefService = CC["@mozilla.org/preferences-service;1"]
.getService(CI.nsIPrefBranch);
var prefRefreshInterval = DEFAULT_REFRESH_INTERVAL;
if (prefService.getPrefType(PREF_ONLINEFAVE_REFRESH_INTERVAL)) {
prefRefreshInterval = prefService.getIntPref(PREF_ONLINEFAVE_REFRESH_INTERVAL);
}
bookmarks = new aService._coop.OnlineBookmarksStream(bookmarks_urn, {
name: aAccountID + " on " + aService.title,
userid: aAccountID,
serviceId: aService.contractId,
favicon: aService.icon,
isTransient: aIsTransient,
refreshInterval: prefRefreshInterval
});
aService._coop.onlinebookmarks_root.children.addOnce(bookmarks);
}
// Create the "no tag" folder
var noTagFolder = new aService._coop.Folder(bookmarks.id() + ":notag", {
name: flockGetString("favorites/favorites", "flock.favs.online.noTag")
});
bookmarks.children.add(noTagFolder);
var acct = aService.getAccount(account_urn);
return acct;
};
onlineFavoritesBackend.removeAccount =
function OFBE_removeAccount(aService, aAccountUrn) {
var acctCoopObj = aService._coop.get(aAccountUrn);
var parents = {};
var i;
// Next delete the bookmarks that are solely associated with this account
var bookmarks_urn = aAccountUrn + ":bookmarks";
var bmStream = aService._coop.get(bookmarks_urn);
if (bmStream) {
aService._logger.debug("found bookmark stream " + bookmarks_urn);
// Remove the Delicious Bookmarks node from its parents
parents = bmStream.getParents();
for (i = 0; i < parents.length; i++) {
parents[i].children.remove(bmStream);
}
} else {
aService._logger.debug("DID NOT find bookmark stream " + bookmarks_urn);
}
// Next remove the account from any parents it might have
parents = acctCoopObj.getParents();
for (i = 0; i < parents.length; i++) {
aService._logger.debug("removing from parent " + i);
parents[i].children.remove(acctCoopObj);
}
// kill the account node
aService._logger.debug("destroying account " + aAccountUrn);
acctCoopObj.destroy();
// Finally, slowly delete the bookmarks
var synchronize = function OFBE_removeAccount_sync(should_yield) {
var i = 0;
var bmChildren = bmStream.children.enumerate();
while (bmChildren.hasMoreElements()) {
var tag = bmChildren.getNext();
var enum_ = tag.children.enumerate();
while (enum_.hasMoreElements()) {
var bm = enum_.getNext();
aService._logger.debug("destroying bookmark " + bm.URL);
var parents = bm.getParents();
for (var j = 0; j < parents.length; j++) {
parents[j].children.remove(bm);
}
bm.destroy();
if (should_yield()) {
yield;
}
}
}
bmStream.destroy();
};
if (bmStream) {
FlockScheduler.schedule(null, 0.1, 10, synchronize);
}
};
onlineFavoritesBackend.updateBookmark =
function OFBE_updateBookmark(aService, aAccountUrn, aServerBookmark, aPrivate) {
var bookmark_urn = aAccountUrn + ":" + aServerBookmark.URL;
var localBookmark = null;
var tagList;
var i;
// Create/update the bookmark itself
if (aService._coop.Bookmark.exists(bookmark_urn)) {
// Need to check if any modification is needed before we assert anything
localBookmark = aService._coop.get(bookmark_urn);
if (bookmarks_match(aServerBookmark, localBookmark)) {
aService._logger.debug("Unchanged on server: Ignoring "
+ aServerBookmark.URL);
return;
}
aService._logger.debug("Modified on server : Updating "
+ aServerBookmark.URL);
if (stringify(aServerBookmark.name) !== stringify(localBookmark.name)) {
localBookmark.name = aServerBookmark.name;
}
if (stringify(aServerBookmark.description) !==
stringify(localBookmark.description))
{
localBookmark.description = aServerBookmark.description;
}
if (sanitizeTags(aServerBookmark.tags) !==
sanitizeTags(localBookmark.tags))
{
localBookmark.tags = sanitizeTags(aServerBookmark.tags);
var tagenum = localBookmark.tag.enumerate();
while (tagenum.hasMoreElements()) {
var tag = tagenum.getNext();
localBookmark.tag.remove(tag);
}
}
var date = new Date();
localBookmark.LastModifiedDate = date;
localBookmark.private = aPrivate;
} else {
// New bookmark
aService._logger.debug("New on server : Creating "
+ aServerBookmark.URL);
localBookmark = new aService._coop.Bookmark(bookmark_urn, {
URL: aServerBookmark.URL,
name: aServerBookmark.name,
description: aServerBookmark.description,
tags: aServerBookmark.tags,
datevalue: aServerBookmark.datevalue,
hash: aServerBookmark.hash,
flockType: "bookmark",
private: aPrivate,
isPollable: false
});
// bookmarks.children.add(localBookmark);
}
tagList = aServerBookmark.tags.split(/[\s,]/);
for (i = 0; i < tagList.length; i++) {
localBookmark.tag.addOnce(tagList[i]);
}
var bookmarks = aService._coop.get(aAccountUrn + ":bookmarks");
this.classifyBookmark(aService, bookmarks, localBookmark, tagList);
};
onlineFavoritesBackend.classifyBookmark =
function OFBE_classifyBookmark(aService, aBookmarks,
aLocalBookmark, aTagList) {
var i;
// Delete the bookmark from the tag folders, and delete empty tags
var parents = aLocalBookmark.getParents();
while (parents.length > 0) {
var parent_ = parents.pop();
parent_.children.remove(aLocalBookmark);
if (!parent_.children.count()) {
aBookmarks.children.remove(parent_);
parent_.destroy();
}
}
var tagFolder;
// Add the bookmark to the tag folders it should be
if ((aTagList.length === 1 && !aTagList[0].length) ||
(!aTagList.length) ||
(aTagList === [""]))
{
var noTagUrn = aBookmarks.id() + ":notag";
tagFolder = aService._coop.get(noTagUrn);
tagFolder.children.add(aLocalBookmark);
} else {
for (i = 0; i < aTagList.length; i++) {
var tagUrn = aBookmarks.id() + ":tag:" + aTagList[i];
if (aService._coop.Folder.exists(tagUrn)) {
tagFolder = aService._coop.get(tagUrn);
} else {
tagFolder = this.createTag(aService, aBookmarks, aTagList[i], tagUrn);
}
tagFolder.children.add(aLocalBookmark);
}
}
};
onlineFavoritesBackend.destroyBookmark =
function OFBE_destroyBookmark(aService, aAccountId, aUrl) {
var bookmark_urn = aService.urn + ":" + aAccountId + ":" + aUrl;
if (aService._coop.Bookmark.exists(bookmark_urn)) {
var bookmarks = aService._coop.get(aService.urn + ":"
+ aAccountId + ":bookmarks");
var bookmark = aService._coop.get(bookmark_urn);
bookmarks.children.remove(bookmark);
bookmark.destroy();
}
};
onlineFavoritesBackend.updateLocal =
function OFBE_updateLocal(aService, aPostsList, aLastUpdate, aAccountUrn) {
var i;
var bmEnum;
var bmEnum2;
// Update the last update time for the bookmark stream
var localBookmarks = aService._coop.get(aAccountUrn + ":bookmarks");
localBookmarks.last_update_time = aLastUpdate;
var be = this;
var synchronize = function OFBE_updateLocal_sync(should_yield) {
var urlHash = {}; // Useful to optimize deletion
// Create new bookmarks, or update existing bookmarks
for (i = 0; i < aPostsList.length; i++) {
if (aPostsList[i].tags === "system:unfiled") {
aPostsList[i].tags = "";
}
// To optimize deletion: put the URLs in a hash
urlHash[aPostsList[i].URL] = true;
be.updateBookmark(aService, aAccountUrn, aPostsList[i]);
if (should_yield()) {
yield;
}
}
// Remove locally bookmarks deleted on the server
var localLength = 0;
i = 0;
bmEnum = localBookmarks.children.enumerate();
while (bmEnum.hasMoreElements()) {
var localTag = bmEnum.getNext();
bmEnum2 = localTag.children.enumerate();
while (bmEnum2.hasMoreElements()) {
var localBookmark = bmEnum2.getNext();
if (!urlHash[localBookmark.URL]) {
aService._logger.debug("Deleted on server : Deleting "
+ localBookmark.URL);
var parents = localBookmark.getParents();
for (var j = 0; j < parents.length; j++) {
parents[j].children.remove(localBookmark);
}
localBookmark.destroy();
}
}
if (should_yield()) {
yield;
}
}
// Remove empty tags
bmEnum = localBookmarks.children.enumerate();
while (bmEnum.hasMoreElements()) {
var tag = bmEnum.getNext();
bmEnum2 = tag.children.enumerate();
if (!bmEnum2.hasMoreElements() &&
(tag.id() !== localBookmarks.id() + ":notag"))
{
// The tag is empty, let's delete it.
// Note: Don't delete "No Tag".
localBookmarks.children.remove(tag);
tag.destroy();
}
}
};
FlockScheduler.schedule(null, 0.1, 10, synchronize);
};
onlineFavoritesBackend.createTag =
function OFBE_createTag(aService, aBookmarks, aTag, aTagUrn) {
var tagFolder = new aService._coop.Folder(aTagUrn,
{ name: aTag }
);
var enum_ = aBookmarks.children.enumerate();
var found = false;
var i = 1;
enum_.getNext(); // Ignore "notag"
while (enum_.hasMoreElements() && !found) {
var currentTag = enum_.getNext();
if (aTag < currentTag.name) {
found = true;
aBookmarks.children.insertAt(tagFolder, i + 1);
}
i++;
}
if (!found) {
aBookmarks.children.add(tagFolder);
}
return tagFolder;
};
onlineFavoritesBackend.updateTags =
function OFBE_updateTags(aService, aAccountId, aTags) {
// Copy aTags, so we can modify it.
var tags = [];
var tag;
var i;
for (i = 0; i < aTags.length; i++) {
tags.push(aTags[i]);
}
// Remove tags no longer present.
var localBookmarks = aService._coop.get(aService.urn + ":"
+ aAccountId + ":bookmarks");
var tagenum = localBookmarks.tag.enumerate();
while (tagenum.hasMoreElements()) {
tag = tagenum.getNext();
if (tags.indexOf(tag) < 0) {
// Not in new array, so remove it.
localBookmarks.tag.remove(tag);
} else {
// Already there, remove from input so we don't try adding it again.
tags.splice(tags.indexOf(tag), 1);
}
}
// Put in the net new tags.
for (i = 0; i < tags.length; i++) {
localBookmarks.tag.addOnce(tags[i]);
}
};
onlineFavoritesBackend.showNotification =
function OFBE_showNotification(aMessage) {
var wm = CC["@mozilla.org/appshell/window-mediator;1"]
.getService(CI.nsIWindowMediator);
var topNavWindow = wm.getMostRecentWindow("navigator:browser");
var nBox = topNavWindow.gBrowser.getNotificationBox();
var notification = nBox.getNotificationWithValue("favorite-error");
if (notification) {
notification.label = aMessage;
} else {
nBox.appendNotification(aMessage,
"favorite-error",
"chrome://browser/skin/Info.png",
nBox.FLOCK_PRIORITY_HIGH,
null);
}
};